import { useCallback, useRef } from 'react';

interface GestureData {
  startTime: number;
  startPosition: { x: number; y: number };
  lastPosition: { x: number; y: number };
  lastTime: number;
  velocityHistory: Array<{ velocity: number; time: number }>;
}

interface UseGestureRecognitionProps {
  /** 最小速度阈值，超过此速度认为是快速滑动 (px/ms) */
  velocityThreshold?: number;
  /** 速度历史记录数量，用于计算平均速度 */
  velocityHistorySize?: number;
  /** 惯性滚动的衰减系数 */
  inertiaDecay?: number;
}

interface GestureResult {
  /** 当前速度 (px/ms) */
  velocity: number;
  /** 是否为快速滑动 */
  isFastSwipe: boolean;
  /** 滑动方向 (-1: 向上/左, 1: 向下/右) */
  direction: number;
  /** 预测的最终位置（考虑惯性） */
  predictedEndPosition: number;
}

/**
 * 手势识别 Hook
 *
 * 🎯 核心设计理念：
 * 1. 速度检测：实时计算滑动速度，识别快速滑动手势
 * 2. 方向判断：根据位移方向确定用户意图
 * 3. 惯性预测：基于当前速度预测释放后的滑动距离
 * 4. 智能吸附：快速滑动时跳过中间吸附点，直达目标位置
 *
 * 🧮 算法原理：
 * - 速度计算：deltaY / deltaTime (px/ms)
 * - 平滑处理：维护速度历史数组，取平均值
 * - 惯性模拟：velocity *= decay，模拟物理衰减
 * - 阈值判断：超过阈值认为是快速滑动
 *
 * 📊 数据结构：
 * - startTime/Position: 手势开始的时间和位置
 * - lastTime/Position: 上一帧的时间和位置
 * - velocityHistory: 速度历史记录，用于平滑计算
 *
 * 🎮 使用场景：
 * - 快速上滑：跳过中间吸附点，直接到顶部
 * - 快速下滑：跳过中间吸附点，直接到底部或关闭
 * - 慢速拖拽：选择最近的吸附点
 *
 * 提供滑动速度检测、手势预测等功能
 */
export const useGestureRecognition = ({
  velocityThreshold = 0.5, // 0.5px/ms = 500px/s
  velocityHistorySize = 5,
  inertiaDecay = 0.95,
}: UseGestureRecognitionProps = {}) => {
  const gestureDataRef = useRef<GestureData | null>(null);

  // 开始手势跟踪
  const startGesture = useCallback((clientX: number, clientY: number) => {
    const now = Date.now();
    gestureDataRef.current = {
      startTime: now,
      startPosition: { x: clientX, y: clientY },
      lastPosition: { x: clientX, y: clientY },
      lastTime: now,
      velocityHistory: [],
    };
  }, []);

  // 更新手势数据
  const updateGesture = useCallback(
    (clientX: number, clientY: number): GestureResult => {
      if (!gestureDataRef.current) {
        return {
          velocity: 0,
          isFastSwipe: false,
          direction: 0,
          predictedEndPosition: 0,
        };
      }

      const now = Date.now();
      const data = gestureDataRef.current;
      const deltaTime = now - data.lastTime;
      const deltaY = clientY - data.lastPosition.y;

      // 计算当前速度
      const currentVelocity = deltaTime > 0 ? deltaY / deltaTime : 0;

      // 更新速度历史
      data.velocityHistory.push({ velocity: currentVelocity, time: now });
      if (data.velocityHistory.length > velocityHistorySize) {
        data.velocityHistory.shift();
      }

      // 计算平均速度
      const avgVelocity =
        data.velocityHistory.reduce((sum, item) => sum + item.velocity, 0) /
        data.velocityHistory.length;

      // 判断滑动方向
      const direction = avgVelocity > 0 ? 1 : avgVelocity < 0 ? -1 : 0;

      // 判断是否为快速滑动
      const isFastSwipe = Math.abs(avgVelocity) > velocityThreshold;

      // 预测惯性滚动的最终位置
      let predictedEndPosition = 0;
      if (isFastSwipe) {
        let velocity = avgVelocity;
        let position = 0;
        // 模拟惯性衰减
        while (Math.abs(velocity) > 0.01) {
          position += velocity * 16; // 假设 60fps，每帧 16ms
          velocity *= inertiaDecay;
        }
        predictedEndPosition = position;
      }

      // 更新位置和时间
      data.lastPosition = { x: clientX, y: clientY };
      data.lastTime = now;

      return {
        velocity: avgVelocity,
        isFastSwipe,
        direction,
        predictedEndPosition,
      };
    },
    [velocityThreshold, velocityHistorySize, inertiaDecay]
  );

  // 结束手势跟踪
  const endGesture = useCallback((): GestureResult => {
    if (!gestureDataRef.current) {
      return {
        velocity: 0,
        isFastSwipe: false,
        direction: 0,
        predictedEndPosition: 0,
      };
    }

    const data = gestureDataRef.current;

    // 计算最终的平均速度
    const avgVelocity =
      data.velocityHistory.length > 0
        ? data.velocityHistory.reduce((sum, item) => sum + item.velocity, 0) /
          data.velocityHistory.length
        : 0;

    const direction = avgVelocity > 0 ? 1 : avgVelocity < 0 ? -1 : 0;
    const isFastSwipe = Math.abs(avgVelocity) > velocityThreshold;

    // 预测惯性滚动的最终位置
    let predictedEndPosition = 0;
    if (isFastSwipe) {
      let velocity = avgVelocity;
      let position = 0;
      while (Math.abs(velocity) > 0.01) {
        position += velocity * 16;
        velocity *= inertiaDecay;
      }
      predictedEndPosition = position;
    }

    // 清理数据
    gestureDataRef.current = null;

    return {
      velocity: avgVelocity,
      isFastSwipe,
      direction,
      predictedEndPosition,
    };
  }, [velocityThreshold, inertiaDecay]);

  return {
    startGesture,
    updateGesture,
    endGesture,
  };
};
